<template>
  <div>
    <div>
      <a-input v-model:value="question"></a-input>
      <div style="float: left">answer:{{ answer }}</div>
    </div>
    <a-divider />
    <a-input v-model:value="some.nested.key"></a-input>
    <div>
      旧的值为：{{ this.some.nested.oldQuestion }} || 新值为：{{
        this.some.nested.newValue
      }}
    </div>
    <a-divider />
    <div>
      <a-image :width="200" :src="long" />
      <span style="margin-left: 8px"
        >姓名：{{ some.man.name.lastName }} {{ some.man.name.firstName }}</span
      >
    </div>
    <p></p>
    <a-button type="primary" @click="changeValue">修改对象的值</a-button>
    <a-divider />
    <a-button type="primary" @click="createWatch"> 创建监听事件</a-button>
    <a-button @click="changeEventValue"> 修改值</a-button>
    <a-button type="primary" danger @click="stopTheWatch">
      销毁监听事件</a-button
    >
    <p>
      {{ eventValue }}
    </p>
  </div>
</template>

<script>
import { notification } from "ant-design-vue";
import { SmileOutlined } from "@ant-design/icons-vue";
import { h } from "vue";
export default {
  data() {
    return {
      eventValue: null,
      count: 0,
      long: require("../../../../public/long.png"),
      question: "",
      answer: "Questions usually contain a question mark. ;-)",
      watchApi: null,
      some: {
        man: {
          name: {
            firstName: "小龙",
            lastName: "李",
          },
        },
        nested: {
          key: null,
        },
        newValue: null,
        oldQuestion: null,
      },
    };
  },
  watch: {
    // 每当 question 改变时，这个函数就会执行
    // eslint-disable-next-line no-unused-vars
    question(newQuestion, oldQuestion) {
      if (newQuestion.includes("?")) {
        this.getAnswer();
      }
    },
    // eslint-disable-next-line no-unused-vars
    "some.nested.key"(newValue, oldQuestion) {
      this.some.nested.newValue = newValue;
      this.some.nested.oldQuestion = oldQuestion;
    },
    some: {
      // eslint-disable-next-line no-unused-vars
      handler(newValue, oldQuestion) {
        this.some = newValue;
      },
      deep: true,
    },
    /**
     * watch 默认是懒执行的：仅当数据源变化时，才会执行回调。但在某些场景中，我们希望在创建侦听器时，立即执行一遍回调
     */
    count: {
      // eslint-disable-next-line no-unused-vars
      handler(newValue, oldQuestion) {
        this.openNotification();
      },
      // 强制立即执行回调
      immediate: true,
      /**
       * 当你更改了响应式状态，它可能会同时触发 Vue 组件更新和侦听器回调。
       * 默认情况下，用户创建的侦听器回调，都会在 Vue 组件更新之前被调用。这意味着你在侦听器回调中访问的 DOM 将是被 Vue 更新之前的状态。
       * 如果想在侦听器回调中能访问被 Vue 更新之后的 DOM，你需要指明 flush: 'post' 选项
       */
      flush: true,
    },
  },
  methods: {
    createWatch() {
      // eslint-disable-next-line no-unused-vars
      this.watchApi = this.$watch("eventValue", (newQuestion, oldQuestion) => {
        notification.open({
          message: "监听事件",
          description: "触发了手动创建的监听事件",
          icon: () =>
            h(SmileOutlined, {
              style: "color: #108ee9",
            }),
        });
      });
    },
    changeEventValue() {
      this.eventValue = Math.random();
    },
    stopTheWatch() {
      this.watchApi();
    },
    openNotification() {
      notification.open({
        message: "监听事件",
        description:
          "watch 默认是懒执行的：仅当数据源变化时，才会执行回调。但在某些场景中，我们希望在创建侦听器时，立即执行一遍回调",
        icon: () =>
          h(SmileOutlined, {
            style: "color: #108ee9",
          }),
      });
    },
    changeValue() {
      this.some = {
        man: {
          name: {
            firstName: "李",
            lastName: "布鲁斯·",
          },
        },
        nested: {
          key: null,
        },
        newValue: null,
        oldQuestion: null,
      };
    },
    async getAnswer() {
      this.answer = "Thinking...";
      try {
        const res = await fetch("https://yesno.wtf/api");
        this.answer = (await res.json()).answer;
      } catch (error) {
        this.answer = "Error! Could not reach the API. " + error;
      }
    },
  },
};
</script>

<style></style>
